package com.tanhua.api.impl.mongo;

import cn.hutool.core.date.DateUtil;
import com.tanhua.api.mongo.SoundApi;
import com.tanhua.domain.mongo.Sound;
import com.tanhua.domain.mongo.SoundDaily;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.lang.Nullable;

@Service
public class SoundApiImpl implements SoundApi {
    // 每日最大接收传音次数
    private static final int dailyMaxReceiveTimes = 10;

    private final MongoTemplate mongoTemplate;

    public SoundApiImpl(@Autowired MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    @Override
    public void send(Sound sound) {
        mongoTemplate.save(sound);
    }

    @Override
    @Nullable
    public Sound receive(Long userId) {
        final Query query = new Query(Criteria.where("userId").ne(userId));
        // 如果 sound 为 null。说明数据中没有传音文件了
        final Sound sound = mongoTemplate.findOne(query, Sound.class);
        if (sound != null) {
            mongoTemplate.remove(sound);
        }

        return sound;
    }

    @Override
    public Integer getRemainingTimesByUserId(Long userId) {
        // 根据用户ID查询今日剩余接收次数
        final Query query = new Query(Criteria.where("userId").is(userId));
        SoundDaily soundDaily = mongoTemplate.findOne(query, SoundDaily.class);
        if (soundDaily == null) {
            soundDaily = new SoundDaily(
                    userId,
                    dailyMaxReceiveTimes
            );
            mongoTemplate.insert(soundDaily);
        }

        final Update update = new Update();

        final Long lastUpdated = soundDaily.getLastUpdated();
        final long today = DateUtil.parse(DateUtil.today(), "yyyy-MM-dd").getTime();

        // 如果上次更新剩余接收次数的时间在今日0点之前，则更新“更新时间”，并重置剩余次数
        if (lastUpdated < today) {
            update.set("lastUpdated", System.currentTimeMillis());
            soundDaily.setRemainingTimes(dailyMaxReceiveTimes);
        }

        // 剩余次数大于等于1则减1
        Integer remainingTimes = soundDaily.getRemainingTimes();
        if (remainingTimes >= 1) {
            remainingTimes = remainingTimes - 1;
            update.set("remainingTimes", remainingTimes);
        }

        // 更新Mongo中该用户数据
        mongoTemplate.upsert(query, update, SoundDaily.class);

        return remainingTimes;
    }
}
